昨天,我們先說明了如何以Flask架設聊天室後端。
今天,我們使用Tailwind CSS和**JavaScript(JS)**來把聊天室的前端完成,而聊天室由上到下分以下幾個部份:
在標題列部份,我設置了一個主題更換按鈕,可以更換成白天/黑夜主題(預設為白天)。
而HTML長這個樣子:
<header class="bg-green-500 text-white p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<h1 class="text-xl font-bold">DialoGPT Chat</h1>
<button id="theme-toggle" class="focus:outline-none">
<i class="fas fa-moon"></i> <!-- 白天/黑夜按鈕 -->
</button>
</div>
</header>
我們在button
標籤設定了theme-toggle
id以撰寫主題更換功能,以下為JS程式碼:
function toggleTheme() {
isDarkMode = !isDarkMode; // isDarkMode初始為false
if (isDarkMode) {
$('body').addClass('bg-gray-900 text-white');
$('.bg-white').addClass('bg-gray-800').removeClass('bg-white');
$('#theme-toggle i').removeClass('fa-moon').addClass('fa-sun');
} else {
$('body').removeClass('bg-gray-900 text-white');
$('.bg-gray-800').addClass('bg-white').removeClass('bg-gray-800');
$('#theme-toggle i').removeClass('fa-sun').addClass('fa-moon');
}
}
$('#theme-toggle').click(toggleTheme); // 若主題按鈕被點選就更換主題
實際使用則是這樣:
HTML的部份沒啥大問題,就是input
標籤。
為了存取使用者輸入的訊息,我們需在輸入標籤加上send-button
id,
好讓我們用JS將訊息傳遞至後端。
<!-- Input area -->
<div class="bg-white border-t border-gray-200 p-4">
<div class="container mx-auto flex space-x-2">
<input type="text" id="user-input" placeholder="Type a message..." class="flex-1 px-4 py-2 border border-gray-300 rounded-full focus:outline-none focus:ring-2 focus:ring-green-500">
<button id="send-button" class="px-6 py-2 bg-green-500 text-white rounded-full hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
輸入框的樣式就長這樣子:
我們來複習一下昨天的Falsk程式碼,
@app.route('/chat', methods=['POST'])
def chat():
...
response = tokenizer.decode(chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
return jsonify({'response': response})
在訊息路由chat()
的開頭,我們以@app.route('/chat')
來設定GPT的回覆要傳送到哪個路徑,且末尾我們以jsonify()
將GPT的回覆包成JSON格式並回傳,方便讓JS去存取和處理訊息。
那在前端就用AJAX將/chat
接收到的JSON格式訊息處理成文字訊息,
並用addMessage()
和formatTime()
將文字訊息渲染成像LINE一樣的訊息泡泡,最後顯示在訊息視窗上。
function formatTime(date) {
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
function addMessage(sender, message) {
const time = formatTime(new Date());
const alignClass = sender === 'You' ? 'justify-end' : 'justify-start';
const bgColorClass = sender === 'You' ? 'bg-green-500 text-white' : 'bg-gray-200 text-gray-800';
$('#chat-container').append(`
<div class="flex ${alignClass}">
<div class="max-w-xs lg:max-w-md">
<div class="${bgColorClass} rounded-lg px-4 py-2 inline-block">
<p class="font-bold">${sender}</p>
<p>${message}</p>
</div>
<p class="text-xs text-gray-500 mt-1">${time}</p>
</div>
</div>
`);
$('#chat-container').scrollTop($('#chat-container')[0].scrollHeight);
}
$('#send-button').click(function() {
var userInput = $('#user-input').val();
if (userInput.trim() !== '') {
addMessage('You', userInput);
$('#user-input').val('');
$.ajax({
url: '/chat',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({message: userInput}),
success: function(response) {
addMessage('Bot', response.response);
}
});
}
});
$('#user-input').keypress(function(e) {
if (e.which == 13) {
$('#send-button').click();
}
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DialoGPT Chat</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 h-screen flex flex-col">
<!-- Header -->
<header class="bg-green-500 text-white p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<h1 class="text-xl font-bold">DialoGPT Chat</h1>
<button id="theme-toggle" class="focus:outline-none">
<i class="fas fa-moon"></i>
</button>
</div>
</header>
<!-- Chat container -->
<div id="chat-container" class="flex-1 overflow-y-auto p-4 space-y-4"></div>
<!-- Input area -->
<div class="bg-white border-t border-gray-200 p-4">
<div class="container mx-auto flex space-x-2">
<input type="text" id="user-input" placeholder="Type a message..." class="flex-1 px-4 py-2 border border-gray-300 rounded-full focus:outline-none focus:ring-2 focus:ring-green-500">
<button id="send-button" class="px-6 py-2 bg-green-500 text-white rounded-full hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
<script>
$(document).ready(function() {
let isDarkMode = false;
function toggleTheme() {
isDarkMode = !isDarkMode;
if (isDarkMode) {
$('body').addClass('bg-gray-900 text-white');
$('.bg-white').addClass('bg-gray-800').removeClass('bg-white');
$('#theme-toggle i').removeClass('fa-moon').addClass('fa-sun');
} else {
$('body').removeClass('bg-gray-900 text-white');
$('.bg-gray-800').addClass('bg-white').removeClass('bg-gray-800');
$('#theme-toggle i').removeClass('fa-sun').addClass('fa-moon');
}
}
$('#theme-toggle').click(toggleTheme);
function formatTime(date) {
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
function addMessage(sender, message) {
const time = formatTime(new Date());
const alignClass = sender === 'You' ? 'justify-end' : 'justify-start';
const bgColorClass = sender === 'You' ? 'bg-green-500 text-white' : 'bg-gray-200 text-gray-800';
$('#chat-container').append(`
<div class="flex ${alignClass}">
<div class="max-w-xs lg:max-w-md">
<div class="${bgColorClass} rounded-lg px-4 py-2 inline-block">
<p class="font-bold">${sender}</p>
<p>${message}</p>
</div>
<p class="text-xs text-gray-500 mt-1">${time}</p>
</div>
</div>
`);
$('#chat-container').scrollTop($('#chat-container')[0].scrollHeight);
}
$('#send-button').click(function() {
var userInput = $('#user-input').val();
if (userInput.trim() !== '') {
addMessage('You', userInput);
$('#user-input').val('');
$.ajax({
url: '/chat',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({message: userInput}),
success: function(response) {
addMessage('Bot', response.response);
}
});
}
});
$('#user-input').keypress(function(e) {
if (e.which == 13) {
$('#send-button').click();
}
});
});
</script>
</body>
</html>